package com.dongwu.manager.service.impl;

import com.dongwu.common.dao.DynamicSpecifications;
import com.dongwu.common.dao.SearchFilter;
import com.dongwu.common.service.impl.BaseServiceImpl;
import com.dongwu.common.utils.HttpUtil;
import com.dongwu.common.utils.UserUtils;
import com.dongwu.config.Slink;
import com.dongwu.manager.dao.DeviceProductRecordDao;
import com.dongwu.manager.dao.ProductDao;
import com.dongwu.manager.dto.ProductData;
import com.dongwu.manager.dto.SpecificationData;
import com.dongwu.manager.entity.AdsClassify;
import com.dongwu.manager.entity.DeviceProductRecord;
import com.dongwu.manager.entity.Product;
import com.dongwu.manager.service.AdsClassifyService;
import com.dongwu.manager.service.ProductService;
import com.dongwu.security.entity.User;
import com.dongwu.security.service.IUserService;
import com.gexin.fastjson.JSONArray;
import com.gexin.fastjson.JSONObject;
import com.google.common.base.Function;
import com.google.common.base.Splitter;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import javax.transaction.Transactional;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.net.URISyntaxException;
import java.util.*;

@Service
public class ProductServiceImpl extends BaseServiceImpl<Product, String> implements ProductService {
	@Autowired
	private IUserService userService;
	@Autowired
	private ProductDao productDao;
	@Autowired
	private DeviceProductRecordDao dprd;
	@Autowired
	private AdsClassifyService adsClassifyService;
	
	@Value("${dongwu.importProductApi}")
	private String importProductApi;
	
	Class<Product> entityClass = null;

	@SuppressWarnings("unchecked")
	public ProductServiceImpl() {
		Type t = getClass().getGenericSuperclass();
		if (t instanceof ParameterizedType) {
			Type[] p = ((ParameterizedType) t).getActualTypeArguments();
			entityClass = (Class<Product>) p[0];
		}
	}
	@Override
	public void delete(List<DeviceProductRecord> records, String id) {
		// TODO Auto-generated method stub
		for (DeviceProductRecord deviceProductRecord : records) {
			if(deviceProductRecord.getProductid().equals(id)){
				dprd.delete(deviceProductRecord);	
			}
		}
		baseRepository.delete(id);

	}

	@Override
	public void delete(List<DeviceProductRecord> records, String[] ids) {
		// TODO Auto-generated method stub
		for (int i = 0; i < ids.length; i++) {
			
			// 删除商品的投放记录再删除商品
			for (DeviceProductRecord deviceProductRecord : records) {
				if(deviceProductRecord.getProductid().equals(ids[i])){
					dprd.delete(deviceProductRecord);	
				}
			}
			delete(ids[i]);
		}
	}

	@Override
	public Product save(Product entity) {
		
		if (entity.getUser() == null) {
			entity.setUser(userService.findByLoginName(UserUtils.getUserLoginName()));
		}
		// 调用短链系统创建
		entity.setSlink(Slink.getSlink(entity.getPathUrl()));
		
		if (entity.getSpeVal() != null && entity.getSpeName() != null) {
			String specification = "";
			String[] speVal = entity.getSpeVal().split("-");
			String[] speName = entity.getSpeName().split(",");
			for (int i = 0; i < speVal.length; i++) {
				if (speVal[i].indexOf(",") == 0) {
					speVal[i] = speVal[i].substring(1, speVal[i].length() - 1);
				}
				speVal[i] = speVal[i].substring(0, speVal[i].length() - 1);
			}
			for (int a = 0; a < speName.length; a++) {
				specification += speName[a] + ":" + speVal[a] + ",|";
			}
			entity.setSpecification(specification);
		}
		return super.save(entity);
	}

	@Override
	@Transactional
	public void syncProduct(List<ProductData> datas) {
		final User admin = userService.findByLoginName("admin");
		final Map<String, User> map = Maps.newHashMap();
		List<Product> products = Lists.transform(datas, new Function<ProductData, Product>() {
			@Override
			public Product apply(ProductData productData) {
				Product product = new Product();
				BeanUtils.copyProperties(productData, product);
				product.setPathUrl(productData.getPathmobile());
				product.setSpecification(productData.getSpecificationItem());
				product.setBussinesName(productData.getBussinesName());
				product.setBussinesSn(productData.getBussinesSn());
				product.setType(Product.Type.outimport);
				User user = null;
				if (StringUtils.isEmpty(productData.getBussinesSn())) {
					user = admin;
				} else {
					if (map.containsKey(productData.getBussinesSn())) {
						user = map.get(productData.getBussinesSn());
					} else {
						user = userService.findByOutSn(productData.getBussinesSn());
						if (user == null) {
							user = admin;
						}
						map.put(productData.getBussinesSn(), user);
					}
				}

				product.setUser(user);
				return product;
			}
		});
		this.batchInsert(products);

	}

	@Override
	@Transactional
	public void importProduct(List<ProductData> datas) {
		User user = userService.findByLoginName(UserUtils.getUserLoginName());
		List<Product> inserts = Lists.newArrayList();
		List<Product> updates = Lists.newArrayList();
		for (ProductData p : datas) {
			Product product = new Product();
			BeanUtils.copyProperties(p, product);
			product.setPathUrl(p.getPathmobile());
			product.setSpecification(p.getSpecificationItem());
			product.setBussinesName(p.getBussinesName());
			product.setBussinesSn(p.getBussinesSn());
			product.setType(Product.Type.outimport);
			product.setUser(user);
			AdsClassify ads = adsClassifyService.queryByCategoryId(p.getCategoryId());
			if(ads == null){
				AdsClassify adsClassify = new AdsClassify();
				adsClassify.setName(p.getCategoryName());
				adsClassify.setCategoryId(p.getCategoryId());
				adsClassify.setType("1");
				adsClassifyService.save(adsClassify);
				product.setAdsClassify(adsClassify);
			}else{
				if(!ads.getName().equals(p.getCategoryName())){
					ads.setName(p.getCategoryName());
					adsClassifyService.update(ads);
				}
				product.setAdsClassify(ads);
			}
			Product pp = productDao.getByUserAndGoodsid(p.getGoodsid(), user.getId());
			if (pp != null) {
				product.setId(pp.getId());
				updates.add(product);
			} else {
				inserts.add(product);
			}
		}
		if (!inserts.isEmpty()) {
			this.batchInsert(inserts);
		}

		if (!updates.isEmpty()) {
			this.batchUpdate(updates);
		}

	}

	@Override
    @Transactional
	public int searchYKProduct(String yunkeNum, int pageNo, int pageSize,List<ProductData> products) throws IOException, URISyntaxException {
		User user = userService.findByLoginName(UserUtils.getUserLoginName());
		Map<String,String> map = new HashMap<>();
		map.put("inviteCode",yunkeNum);
		map.put("pageNo", pageNo+"");
		map.put("pageSize", pageSize + "");
		map.put("type", 1 + "");
		JSONObject jsStr = JSONObject.parseObject(HttpUtil.getInstance().respEntity2String( HttpUtil.getInstance().doPostStrE(importProductApi, JSONObject.toJSONString(map))));
		int count=0;
		JSONArray jsonArray = jsStr.getJSONArray("goods");
		if(jsonArray != null){
			count=jsStr.getIntValue("count");
			for(int i=0; i<jsonArray.size();i++){
				ProductData productData = new ProductData();
				JSONObject job = jsonArray.getJSONObject(i);
				productData.setName(job.get("goodsname").toString());
				productData.setPrice(new BigDecimal(job.get("reducedprice").toString()));
                String s = job.get("integral").toString();
                int a = s.indexOf(".");
				productData.setRewardPoint(Long.valueOf(s.substring(0,a)));
				productData.setSlideImage(job.get("imgurl").toString());
				productData.setIntroduction(job.get("detail").toString());
				productData.setImage(job.get("smallurl").toString());
				productData.setGoodsid(job.get("goodsid").toString());
				productData.setSpecificationItem(job.get("specification").toString());
                productData.setCategoryName(job.get("categoryname").toString());
				productData.setCategoryId(Integer.parseInt(job.get("categoryid").toString()));
                productData.setIshot(Integer.parseInt(job.get("ishot").toString()));
				Product product =productDao.getByUserAndGoodsid(job.get("goodsid").toString(), user.getId());
				if(product == null){
					productData.setIsexit(false);
				}else{
					productData.setIsexit(true);
				}
				products.add(productData);
			}
		}
		return count;
	}

	@Override
	@Transactional
	public void syncYKProduct(String yunkeNum, int pageNo, int pageSize) throws Exception {
		User user = userService.findByLoginName(UserUtils.getUserLoginName());
		Map<String,String> map = new HashMap<>();
		map.put("inviteCode",yunkeNum);
		map.put("pageNo", pageNo+"");
		map.put("pageSize", pageSize + "");
		map.put("type", 2 + "");
		JSONObject jsStr = JSONObject.parseObject(HttpUtil.getInstance().respEntity2String( HttpUtil.getInstance().doPostStrE(importProductApi, JSONObject.toJSONString(map))));
		JSONArray jsonArray = jsStr.getJSONArray("goods");
		List<Product> products = Lists.newArrayList();
		List<String> queryProducts = Lists.newArrayList();
		if(jsonArray != null){
			for (int i = 0; i < jsonArray.size(); i++) {
				JSONObject job = jsonArray.getJSONObject(i);
				Product product =productDao.getByUserAndGoodsid(job.get("goodsid").toString(), user.getId());
				if(product != null){
					product.setName(job.get("goodsname").toString());
					product.setPrice(new BigDecimal(job.get("reducedprice").toString()));
					String s = job.get("integral").toString();
					int a = s.indexOf(".");
					product.setRewardPoint(Long.valueOf(s.substring(0, a)));
					product.setSlideImage(job.get("imgurl").toString());
					product.setIntroduction(job.get("detail").toString());
					product.setImage(job.get("smallurl").toString());
					product.setGoodsid(job.get("goodsid").toString());
					product.setIshot(Integer.parseInt(job.get("ishot").toString()));
					AdsClassify ads = adsClassifyService.queryByCategoryId(Integer.parseInt(job.get("categoryid").toString()));
					if(ads == null){
						AdsClassify adsClassify = new AdsClassify();
						adsClassify.setName(job.get("categoryname").toString());
						adsClassify.setCategoryId(Integer.parseInt(job.get("categoryid").toString()));
						adsClassify.setType("1");
						adsClassifyService.save(adsClassify);
						product.setAdsClassify(adsClassify);
					}else{
						if(!ads.getName().equals(job.get("categoryname").toString())){
							ads.setName(job.get("categoryname").toString());
							adsClassifyService.update(ads);
						}
						product.setAdsClassify(ads);
					}
					if("1".equals(job.get("status").toString())){
						products.add(product);
					}else{
						queryProducts.add(product.getId());
					}
				}
			}
		}

		if (!products.isEmpty()) {
			this.batchUpdate(products);
		}
		String[] strings = new String[queryProducts.size()];
		for(int i = 0; i < queryProducts.size(); i++){
			strings[i] = queryProducts.get(i);
		}
		if(!queryProducts.isEmpty()){
			List<DeviceProductRecord> records = dprd.getDeviceProductRecord(queryProducts);
			if(strings.length > 0){
				delete(records, strings);
			}
		}

	}

	@Override
	public Product get(String id) {
		Product product = baseRepository.findOne(id);
		if (product == null) {
			throw new RuntimeException(String.format("找不到id=%s的对象", id));
		}
		// 如果规格不为空则处理规格数据
		if (!StringUtils.isEmpty(product.getSpecification())) {
			Map<String, String> join = Splitter.on("|").trimResults().omitEmptyStrings().withKeyValueSeparator(":")
					.split(product.getSpecification());

			Set<String> keyset = join.keySet();
			List<SpecificationData> sps = Lists.newArrayList();
			for (String key : keyset) {
				SpecificationData sp = new SpecificationData();
				sp.setSpecification_name(key);
				sp.setSpecification(Splitter.on(",").trimResults().omitEmptyStrings().splitToList(join.get(key)));
				sps.add(sp);
			}
			product.setSpecificationList(sps);
		}
		return super.save(product);
	}

//	@Override
//	public List<ProductData> findByDeviceId(String deviceid) {
//		List<DeviceProductRecord> records = deviceProductRecordService.findByDeviceid(deviceid);
//		// 循环判断当前时间是否在投放设定的时间内,如果不在当前时间内则删除
//		if (records != null) {
//			for (int i = 0; i < records.size(); i++) {
//				// 如果两个时间都是null时则永久展示
//				if (records.get(i).getStartTime() != null || records.get(i).getEndTime() != null) {
//					// 开始和结束时间都不为空时
//					if (records.get(i).getStartTime() != null && records.get(i).getEndTime() != null) {
//						// 判断如果当前时间不在范围内删除这条
//						if (!DateUtils.belongCalendarBetterwin(records.get(i).getStartTime(),
//								records.get(i).getEndTime())) {
//							records.remove(records.get(i));
//							i = i - 1;
//							continue;
//						}
//					}
//					// 只设置了开始时间
//					if (records.get(i).getStartTime() != null && records.get(i).getEndTime() == null) {
//						// 判断如果当前时间在开始时间之前则不显示
//						if (DateUtils.belongCalendarBefore(records.get(i).getStartTime())) {
//							records.remove(records.get(i));
//							i = i - 1;
//							continue;
//						}
//					}
//					// 只设置了结束时间（今天到结束之间为展示时间）
//					if (records.get(i).getStartTime() == null && records.get(i).getEndTime() != null) {
//						// 判断如果当前时间在结束时间之后则不显示
//						if (DateUtils.belongCalendarAfter(records.get(i).getEndTime())) {
//							records.remove(records.get(i));
//							i = i - 1;
//							continue;
//						}
//					}
//				}
//			}
//		}
//		Function<DeviceProductRecord, ProductData> function = new Function<DeviceProductRecord, ProductData>() {
//			@Override
//			public ProductData apply(DeviceProductRecord input) {
//				ProductData data = new ProductData();
//				data.setId(input.getProductid());
//				data.setName(input.getProduct().getName());
//				data.setImage(input.getProduct().getImage());
//				return data;
//			}
//		};
//		return Lists.transform(records, function);
//	}

	@Override
	public Product update(Product entity) {
		if (entity.getSpeVal() != null && entity.getSpeName() != null) {
			String specification = "";
			String[] speVal = entity.getSpeVal().split("-");
			String[] speName = entity.getSpeName().split(",");
			for (int a = 0; a < speName.length; a++) {
				specification += speName[a] + ":" + speVal[a] + ",|";
			}
			entity.setSpecification(specification);
		}
		return super.save(entity);
	}

	@Override
	public Long getCount(Map<String, Object> searchParams, String userId) {
		Long devList=null;
		if(userId == null){
			// TODO Auto-generated method stub
			Map<String, SearchFilter> filters = SearchFilter.parse(searchParams);
			Specification<Product> spec = DynamicSpecifications.bySearchFilter(filters.values(), entityClass);
			// 返回当前用户的所有投放记录
			devList = productDao.count(spec);
		}else{
			devList = productDao.countByUserid(userId);
		}
		return devList;
		
	}
	@Override
	public List<Product> findBySort(Sort sort) {
		return productDao.findAll(sort);
	}
	@Override
	public List<Product> getProductForDevId(String deviceId, String classifyId) {
		List<Product> p = productDao.getProductForDevId(deviceId, classifyId);
		for (Product product : p) {
			// 调用短链系统创建
			if(product.getSlink() == null){
				product.setSlink(Slink.getSlink(product.getPathUrl()));
			}
		}
		return p;
	}

}
